home *** CD-ROM | disk | FTP | other *** search
- Subject: v08i064: The VN news reader, Part01/03
- Newsgroups: mod.sources
- Approved: mirror!rs
-
- Submitted by: rtech!bobm (Bob Mcqueer)
- Mod.sources: Volume 8, Issue 64
- Archive-name: vn/Part01
-
- This is the source for the alternate news reader vn. I'm sending
- you the four archives I put up in net.sources as four separate
- mail messages. Archive 1 contains documentation and a README file
- concerning installation. I tried to make these archives about the
- size that seemed to be acceptable in existing mod.sources postings -
- about 40K each. If you are a devoted user of the other readers, copy
- your .newsrc before you give this one a try - you might not like what
- it does. My justification is that a pretty fair number of people DO
- like what it does - consider it an alternate paradigm which basically
- got its start a few years back because I was getting sick of beating
- on the 'n' key.
-
- Bob McQueer
- {amdahl, sun, mtxinu, hoptoad, cpsc6a}!rtech!bobm
-
- [ We use notes internally -- I haven't tried this. --r$ ]
- #! /bin/sh
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- # If all goes well, you will see the message "End of archive 1 (of 3)."
- # Contents: MANIFEST README config.h digest.c envir_set.c groupdir.c
- # hash.c head.h mf.nore mf.re mf.sysv newsrc.c pagefile.c reader.h
- # reg.c sig_set.c storage.c strings.c tmpnam.c
- # Wrapped by rs@mirror on Tue Feb 17 12:10:01 1987
- PATH=/bin:/usr/bin:/usr/ucb; export PATH
- echo shar: extracting "'MANIFEST'" '(974 characters)'
- if test -f 'MANIFEST' ; then
- echo shar: will not over-write existing file "'MANIFEST'"
- else
- sed 's/^X//' >MANIFEST <<'@//E*O*F MANIFEST//'
- X File Name Kit # Description
- X-----------------------------------------------------------
- X MANIFEST 1
- X README 1
- X config.h 1
- X digest.c 1
- X envir_set.c 1
- X groupdir.c 1
- X hash.c 1
- X head.h 1
- X mf.nore 1
- X mf.re 1
- X mf.sysv 1
- X newsrc.c 1
- X pagefile.c 1
- X reader.c 2
- X reader.h 1
- X reg.c 1
- X sig_set.c 1
- X storage.c 1
- X strings.c 1
- X strtok.c 2
- X term_set.c 2
- X tmpnam.c 1
- X tty.h 2
- X tty_set.c 2
- X tune.h 2
- X userlist.c 2
- X vn.c 3
- X vn.h 2
- X vn.man 3
- X vnglob.c 2
- @//E*O*F MANIFEST//
- if test 974 -ne "`wc -c <'MANIFEST'`"; then
- echo shar: error transmitting "'MANIFEST'" '(should have been 974 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'README'" '(7590 characters)'
- if test -f 'README' ; then
- echo shar: will not over-write existing file "'README'"
- else
- sed 's/^X//' >README <<'@//E*O*F README//'
- XInstallation procedure steps:
- X
- X1) Edit file config.h, which defines system dependent parameters such as
- Xspool directory, and so on. I have NOT ifdef'ed this file for likely
- Xchanges for SYSV or anything like that. You probably can use this file
- Xuntouched only if you are UCB with news installed in all the standard places.
- XEven then, you may not like some of the defaults.
- X
- XNote very carefully the definitions involving mailer treatment.
- X
- X2) decide which makefile to use, edit it to fill in the correct libraries
- Xfor your system. See notes 2) below for explanation.
- X
- X3) make vn
- X
- X4) put the executable where you want it. put the man page, vn.man
- Xwhere you want it. roff it with -man to print it out. If you made
- Xsome configuration changes, or you are a SYSV installation, you may
- Xwant to modify the manual a bit. It is written to reflect the actions in
- Xthe config.h as distributed, and as used on UCB (it refers to job control).
- X
- XNotes:
- X
- X1)
- X If you modify the default mailer, poster, printer or editor, this is
- X their invocation, ufile being a tempfile name.
- X
- X "mailer [path] <ufile" - path obtained from newsarticle, possibly
- X modified by user. May be invoked with no argument dependent
- X on how you set up config.h. No path argument if INLETTER.
- X "poster <ufile" - thus the "inews -h" to get header lines from
- X file, giving user a chance to modify headers.
- X "printer files 2>/dev/null"
- X "editor ufile"
- X
- X You may also be interested in the header file "tune.h" which contains
- X some sizing / performance affecting parameters.
- X
- X2)
- X There are three makefile templates, all very simple, because I
- X want to make you think about whether you have the system V regular
- X expression library, and strtok() or not. If you have regex and
- X regcmp (as opposed to re_exec and re_comp, the ucb regular
- X expression library), I advise you to use them. regex and
- X regcmp are used because they have the ability to keep several
- X regular expressions compiled at once. The file "reg.c" is an
- X implementation of regcmp and regex on top of the ucb calls,
- X with a special procedure called "regfree" used in place of the
- X generic "free" call used with regcmp / regex. Use the system V
- X calls if you have them available because:
- X
- X i) They should be faster than the reg.c code, which
- X recompiles the "current" ucb string every time you
- X switch regular expressions.
- X
- X ii) I briefly checked out reg.c once, and it seemed to
- X work. Our system has the "real" calls available, so I
- X run with those. reg.c hasn't been used much by me, although
- X I've had nobody tell me it doesn't work.
- X
- X strtok.c defines the strtok() and strpbrk() functions. As with
- X regex, if you have system libraries, they are likely more efficient -
- X these string routines will often be done in assembler on a given
- X machine.
- X
- X tmpnam.c defines the tmpnam() routine. Even if a BSD system has it,
- X you might use it anyhow. We are currently running under Ultrix on a
- X microvax, and in fact, the Ultrix version doesn't work right (as of
- X the last time I checked). Also, the tmpnam.c version will produce
- X temp files named vnXXXXXX, instead of a generic tmpXXXXXX.
- X
- X There are 2 IFDEF's handled in the makefile templates:
- X
- X SYSV - system V specific portions.
- X
- X JOBCONTROL - brackets the parts dealing with the SIGTSTP
- X signal handling for job control. This could really
- X be done with "#ifndef SYSV", I suppose, but this
- X clearly marks this specific difference.
- X
- X The ifdef OLDRC may be set to make the .newsrc format consistent
- X with an apparently earlier readnews format which would not take
- X ranges for "articles read". This also makes -i an alias for a -x
- X option, and assumes that any arguments with no options are really
- X -n options. These changes came from Australia, and are apparently
- X compatible with whatever other newsreader was being used there.
- X
- X SYSV, JOBCONTROL, OLDRC and the definitions referred to in config.h
- X are the whole set.
- X
- X If you are BSD but have regex/regcomp:
- X
- X mf.re is the makefile template. Fill in your local
- X libraries (termcap), the library to find regex/regcmp in.
- X This makefile defines "regfree" simply to be "free", and
- X doesn't link the "reg" object. JOBCONTROL defined. This
- X template also assumes you have strtok() / strpbrk(). If you
- X don't, include strtok.o in the objects. This is actually
- X the makefile I use for Ultrix as given.
- X
- X If you are BSD but don't have regex/regcomp:
- X
- X mf.nore is the makefile template. Fill in your local
- X libraries (termcap). This makefile pulls in the "reg"
- X object. JOBCONTROL defined. If you DO have strtok() /
- X strpbrk() available, you might remove strtok.o from the
- X object list.
- X
- X If you are SYS V:
- X
- X mf.sysv is the makefile template. Fill in your local
- X libraries (termcap). This makefile does not pull in
- X the extra objects. It defines "regfree" to "free", and
- X turns the BSD index / rindex into strchr / strrchr.
- X SYSV defined.
- X
- X I haven't personally tried any SYSV stuff out - I don't have
- X access to a SYS V machine running news. You might want to
- X include tmpnam.o in the object list instead of using the
- X standard one, to get specifically named temp. files.
- X
- X Something pretty close to the current vn version used to run here
- X on a VAX 780 under BSD 4.2.
- X
- XNEWS VERSIONS:
- X
- XI know there's a lot of news versions running out there. We seem to
- Xbe running something called B2.10.3, for those of you whom that signifies
- Xanything to. Something to look at is your "active" file. I expect to
- Xfind a newsgroup followed by the high, then low, spooling numbers (followed
- Xby a y/n for posting priveledge, which I don't care about). Earlier news
- Xversions used to only have a single spooling number. vn is written to
- Xhandle this, assuming 0 for a low spool. My basic assumptions are that
- Xthe "active" file gives the newsgroups and spooling information and that
- Xarticles will be numeric filenames living in the directory obtained by
- Xreplacing periods with slashes in the newsgroup, and prefixing the spool
- Xdirectory. I hope these really are "basic" assumptions that work across all
- Xversions. vn is intended to be highly fault-tolerant regarding what it
- Xfinds for header lines - it may not be able to make sense out of an "article",
- Xbut it's willing to let you look at it anyway, with the single exception
- Xthat it throws away articles which turn out to be empty or 1 line files (
- XCOUNTING the header lines - articles with 0 lines in them are OK. I'm
- Xjust preventing the "unknown subject, unknown author, and no text" case).
- X
- XRESOURCE USE:
- X
- Xvn should look like people sitting in an editor once it is done with its
- Xreading phase. During the reading phase, it is beating mercilessly on
- Xthe spooling directory, reading file after file. I have thought from time
- Xto time about having a daemon do this work periodically, building a master
- Xfile of title information for vn to access. Its reading phase would then
- Xbe a "pause" rather than a "phase", with the penalty that you couldn't
- Xread anything until the daemon had gotten around to it.
- X
- Xvn maintains a large temporary file containing the users page screens.
- XAgain, it should look a lot like the user is using an editor which has
- Xa temp file out there for its edit buffer. MAX_C in "tune.h" can be
- Xused to help control the size.
- X
- Xmalloc() usage - Around 50 bytes per newsgroup is dynamically allocated,
- Xplus storage for character strings and the current screen structure.
- XMy guess would be on the order of 20-40K. It's all "permanent" information
- Xmaintained for the entire session, hence unfreed. Regular expression
- Xstorage is freed, but is minimal anyway.
- @//E*O*F README//
- if test 7590 -ne "`wc -c <'README'`"; then
- echo shar: error transmitting "'README'" '(should have been 7590 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'config.h'" '(3422 characters)'
- if test -f 'config.h' ; then
- echo shar: will not over-write existing file "'config.h'"
- else
- sed 's/^X//' >config.h <<'@//E*O*F config.h//'
- X/*
- X** vn news reader.
- X**
- X** config.h - system configuration parameters
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#define DEF_ED "/usr/ucb/vi" /* editor to use if no EDITOR variable */
- X#define DEF_PS1 "$ " /* ! command prompt if no PS1 */
- X#define DEF_SAVE "vn.save" /* save file */
- X
- X/*
- X** mailer interface. If INLETTER is defined, a "To:" line will be
- X** placed in the file being editted by the user. Otherwise, the
- X** address will be an argument on the mailer's command line, with the
- X** user prompted for possible correction. In either case, "Subject: "
- X** is included in the file.
- X**
- X** If MAILSMART is set, alternate header lines will be used instead of
- X** the "Path: " line to determine the address because we assume the mailer
- X** is intelligent enough to do routing.
- X**
- X** If ADDRMUNGE is set, it is the name of a local routine which will be
- X** called to make further address modifications before the address is used.
- X** It will be passed the address string, which it may modify. RECLEN bytes
- X** of storage are available at the address passed. It will only be called
- X** once for a given address.
- X**
- X** DEF_MAIL is the mailer used in absence of MAILER variable.
- X*/
- X#define INLETTER
- X#define MAILSMART
- X#define DEF_MAIL "/usr/lib/sendmail -t"
- X
- X#define DEF_PRINT "/usr/ucb/lpr" /* print command */
- X#define DEF_POST "/usr/lib/news/inews -h" /* followup posting command */
- X
- X#define DEF_NEWSRC ".newsrc"
- X#define DEF_CCFILE "author_copy"
- X#define DEF_KEYXLN ".vnkey"
- X
- X#define SPOOLDIR "/usr/spool/news"
- X#define ACTFILE "/usr/lib/news/active"
- X
- X/*
- X** foreground flag for messages. applies only if JOBCONTROL undefined
- X** (SYS V). set to 1 to see newsgroup messages, etc. during reading phase,
- X** 0 for "silent" operation - be warned that this may suppress some
- X** non-fatal diagnostic messages - find all references to fgprintf to
- X** see what is suppressed.
- X*/
- X#define NOJOB_FG 1
- X
- X/*
- X** arrow key treatment. If PAGEARROW is defined, right and left arrow
- X** keys will be synonyms for <return> (next-page) and <backspace> (previous).
- X** Otherwise, the right arrow will function as down, and the left as up.
- X** Made configurable because while there is no lateral motion on the screen
- X** to associate with the right and left arrows, you might not like them
- X** changing pages on you.
- X*/
- X#define PAGEARROW
- X
- X/*
- X** if USEVS is defined, terminal initialization / exit for vn will include the
- X** "vs"/"ve" pair as well as "ti"/"te". This doesn't matter on a lot of
- X** terminals, but may make vn display behaviour closer to "vi" since vs/ve
- X** is vi's "visual mode" sequence. For instance, I believe the commonly
- X** used definitions for these strings on multi-page concepts allows the
- X** program to run in the first page of the terminal, preserving the more
- X** recent part of your session on exit
- X**
- X** #define USEVS
- X*/
- X
- X/*
- X** temp file name template for mktemp(). Used in tmpnam.c, does not apply
- X** if you use a system library tmpnam(). BE CAREFUL - VNTEMPNAME MUST
- X** contain a string of 6 X's for mktemp() (actually, a place where 6 X's
- X** are intended to go). TMP_XOFFSET absolutely MUST point to the first of
- X** the X's. Yes, writing into a literal string is sloppy. To the best of
- X** my knowledge, tmpnam.c is the only place you'll find vn code doing it.
- X** We make this configurable in case you want temp files somewhere else.
- X*/
- X#define VNTEMPNAME "/usr/tmp/vnXXXXXX"
- X#define TMP_XOFFSET 11
- @//E*O*F config.h//
- if test 3422 -ne "`wc -c <'config.h'`"; then
- echo shar: error transmitting "'config.h'" '(should have been 3422 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'digest.c'" '(5027 characters)'
- if test -f 'digest.c' ; then
- echo shar: will not over-write existing file "'digest.c'"
- else
- sed 's/^X//' >digest.c <<'@//E*O*F digest.c//'
- X/*
- X** vn news reader.
- X**
- X** digest.c - digest unpacking routines
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#include <stdio.h>
- X#include "config.h"
- X#include "vn.h"
- X#include "head.h"
- X
- Xextern int Digest;
- Xextern int L_allow;
- Xextern int C_allow;
- Xextern PAGE Page;
- X
- Xextern char *F_head, *T_head, *L_head, *D_head;
- X
- Xdigest_page (idx,skip)
- Xint idx;
- X{
- X char *ptr,name[24],*title,*index();
- X FILE *fp;
- X int i,len;
- X char subj[RECLEN],date[RECLEN],from[RECLEN],junk[RECLEN],*str_store();
- X long pos;
- X
- X Digest = Page.b[idx].art_id;
- X sprintf (name,"%d", Digest);
- X
- X if ((fp = fopen(name,"r")) == NULL)
- X return (-1);
- X
- X subj[0] = date[0] = from[0] = junk[0] = '\0';
- X
- X skip_header (fp);
- X
- X /* skip over some articles if requested to */
- X for (i=skip; i > 0; --i)
- X {
- X if (dig_advance(fp,from,subj,date,junk,&pos) < 0)
- X return (-1);
- X }
- X
- X /* every new call to a digest Page "loses" a small amount of storage */
- X title = str_store(Page.b[idx].art_t);
- X if ((ptr = index(title,'~')) != 0)
- X *ptr = '\0';
- X title [C_allow - 20] = '\0';
- X
- X for (i=0; i < L_allow &&
- X (len = dig_advance(fp,from,subj,date,junk,&pos)) >= 0; ++i)
- X {
- X Page.b[i].art_id = i+1+skip;
- X Page.b[i].art_mark = ' ';
- X subj [C_allow] = '\0';
- X from [C_allow] = '\0';
- X sprintf (name,"%d",len);
- X form_title (date,subj,name,from,100);
- X strcpy (Page.b[i].art_t,date);
- X }
- X
- X fclose (fp);
- X
- X if (i == 0)
- X return (-1);
- X
- X Page.h.name = title;
- X Page.h.artnum = i;
- X return (i);
- X}
- X
- X/*
- X returns name of file containing "article", NULL for failure
- X*/
- Xchar * digest_extract (s,art)
- Xchar *s;
- Xint art;
- X{
- X char name[24];
- X FILE *fout,*fin;
- X char subj[RECLEN],date[RECLEN],from[RECLEN],bufr[RECLEN];
- X char extra[RECLEN];
- X char *index();
- X long pos;
- X int lines;
- X
- X sprintf (name,"%d", Digest);
- X if ((fin = fopen(name,"r")) == NULL)
- X return (NULL);
- X
- X for (skip_header (fin); art > 0; --art)
- X if ((lines = dig_advance(fin,from,subj,date,extra,&pos)) < 0)
- X {
- X fclose (fin);
- X return (NULL);
- X }
- X
- X tmpnam(s);
- X
- X if ((fout = fopen(s,"w")) == NULL)
- X {
- X fclose (fin);
- X unlink (s);
- X return (NULL);
- X }
- X
- X fseek(fin,0L,0);
- X
- X while (fgets(bufr,RECLEN-1,fin) != NULL && index(bufr,':') != NULL)
- X {
- X if (strncmp(bufr,F_head,FHDLEN) == 0)
- X {
- X fprintf (fout,"%s%s\n",F_head,from);
- X continue;
- X }
- X if (strncmp(bufr,T_head,THDLEN) == 0)
- X {
- X fprintf (fout,"%s%s\n",T_head,subj);
- X continue;
- X }
- X if (strncmp(bufr,D_head,DHDLEN) == 0)
- X {
- X fprintf (fout,"%s%s\n",D_head,date);
- X continue;
- X }
- X /* defer line count header - it comes last */
- X if (strncmp(bufr,L_head,LHDLEN) == 0)
- X continue;
- X fprintf (fout,"%s",bufr);
- X }
- X
- X /* toss in extra header lines, line count header, extra newline */
- X fprintf (fout,"%s%s%d\n\n",extra,L_head,lines);
- X
- X fseek (fin,pos,0);
- X
- X while (fgets(bufr,RECLEN-1,fin) != NULL && strncmp(bufr,"--------",8) != 0)
- X fprintf(fout,"%s",bufr);
- X
- X fclose (fin);
- X fclose (fout);
- X return (s);
- X}
- X
- Xdig_list (s)
- Xchar *s;
- X{
- X char *ptr,*out,*new,ns[L_tmpnam],tmp[RECLEN],*strtok();
- X int i;
- X
- X prinfo ("Extracting articles .....");
- X strcpy (tmp,s);
- X out = s;
- X
- X for (ptr = strtok(tmp," "); ptr != NULL; ptr = strtok(NULL," "))
- X {
- X i = atoi(ptr);
- X if ((new = digest_extract(ns,i)) != NULL)
- X {
- X sprintf (out,"%s ",new);
- X out += strlen(new) + 1;
- X }
- X }
- X
- X *out = '\0';
- X
- X if (*s == '\0')
- X strcpy (s,"NULLDIGEST");
- X}
- X
- Xdig_ulist (s)
- Xchar *s;
- X{
- X char *strtok();
- X for (s = strtok(s," "); s != NULL; s = strtok(NULL," "))
- X unlink (s);
- X}
- X
- X/*
- X returns # lines in article, -1 for failure
- X scans past article, returns position of start.
- X also returns "extra" header lines encountered, WITH newlines.
- X*/
- Xstatic dig_advance (fp,from,subj,date,extra,pos)
- XFILE *fp;
- Xchar *from,*subj,*date,*extra;
- Xlong *pos;
- X{
- X char buf[RECLEN];
- X char *ptr, *index();
- X int len,state,lcount;
- X
- X lcount = state = 0;
- X *extra = '\0';
- X
- X while (fgets(buf,RECLEN-1,fp) != NULL)
- X {
- X buf[(len = strlen(buf) - 1)] = '\0';
- X for (--len ; len >= 0 && buf[len] == ' ' || buf[len] == '\t'; --len)
- X buf[len] = '\0';
- X ++len;
- X
- X switch(state)
- X {
- X case 0:
- X /* skip blank lines before header */
- X if (len == 0)
- X break;
- X state = 1; /* fall through */
- X case 1:
- X if (strncmp(buf,F_head,FHDLEN) == 0)
- X {
- X strcpy (from,buf+FHDLEN);
- X break;
- X }
- X if (strncmp(buf,T_head,THDLEN) == 0)
- X {
- X strcpy (subj,buf+THDLEN);
- X break;
- X }
- X if (strncmp(buf,D_head,DHDLEN) == 0)
- X {
- X strcpy (date,buf+DHDLEN);
- X break;
- X }
- X /* put wierd header lines in extra */
- X if ((ptr = index(buf,':')) != NULL)
- X {
- X *ptr = '\0';
- X if (index(buf, ' ') == NULL)
- X {
- X *ptr = ':';
- X sprintf(extra,"%s\n",buf);
- X extra += strlen(extra);
- X break;
- X }
- X *ptr = ':';
- X }
- X state = 2;
- X
- X /* remember the newline we lopped off */
- X *pos = ftell(fp)-strlen(buf)-1; /* fall through */
- X case 2:
- X ++lcount;
- X if (strncmp("--------",buf,8) == 0)
- X {
- X --lcount;
- X return (lcount);
- X }
- X break;
- X }
- X }
- X
- X return (-1);
- X}
- X
- Xstatic skip_header (fp)
- XFILE *fp;
- X{
- X char buf[RECLEN];
- X
- X while (fgets(buf,RECLEN-1,fp) != NULL)
- X if (strncmp("--------",buf,8) == 0)
- X break;
- X}
- @//E*O*F digest.c//
- if test 5027 -ne "`wc -c <'digest.c'`"; then
- echo shar: error transmitting "'digest.c'" '(should have been 5027 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'envir_set.c'" '(2931 characters)'
- if test -f 'envir_set.c' ; then
- echo shar: will not over-write existing file "'envir_set.c'"
- else
- sed 's/^X//' >envir_set.c <<'@//E*O*F envir_set.c//'
- X/*
- X** vn news reader.
- X**
- X** envir_set.c - routine to obtain pertinent environment variable settings
- X** and set up file / directory names
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#include <stdio.h>
- X#include <pwd.h>
- X#include <sys/param.h>
- X#include "config.h"
- X
- Xextern char *Editor,*Ps1,*Mailer,*Printer,*Poster;
- Xextern char *Onews, *Newsrc, *Orgdir, *Savedir, *Ccfile; /* path names */
- Xextern char Cxitop[], Cxitor[], Cxrtoi[], Cxptoi[];
- X
- X#ifdef SYSV
- Xextern char *getcwd();
- X#define getwd(a) getcwd(a,sizeof(a))
- X#define MAXPATHLEN 240
- X#else
- Xextern char *getwd();
- X#endif
- X
- X/*
- X environment variable, original directory string setup.
- X*/
- X
- Xenvir_set ()
- X{
- X char dbuf [MAXPATHLEN], *rcname, *ccname, *keyxln;
- X char *getenv(), *getcwd(), *str_store();
- X struct passwd *ptr, *getpwuid();
- X
- X if ((Ps1 = getenv("PS1")) == NULL)
- X Ps1 = DEF_PS1;
- X if ((Editor = getenv("EDITOR")) == NULL)
- X Editor=DEF_ED;
- X if ((Mailer = getenv("MAILER")) == NULL)
- X Mailer=DEF_MAIL;
- X if ((Poster = getenv("POSTER")) == NULL)
- X Poster=DEF_POST;
- X if ((Printer = getenv("PRINTER")) == NULL)
- X Printer=DEF_PRINT;
- X if ((rcname = getenv("NEWSRC")) == NULL)
- X rcname=DEF_NEWSRC;
- X if ((ccname = getenv("CCFILE")) == NULL)
- X ccname=DEF_CCFILE;
- X if ((keyxln = getenv("VNKEY")) == NULL)
- X keyxln=DEF_KEYXLN;
- X Savedir = getenv("VNSAVE");
- X
- X /*
- X set original directory strings. create empty Newsrc if it doesn't exist
- X */
- X
- X ptr = getpwuid (getuid());
- X if ((Orgdir = getwd(dbuf)) == NULL)
- X printex ("cannot stat pwd");
- X Orgdir = str_store (Orgdir);
- X if (Savedir == NULL)
- X Savedir = Orgdir;
- X if (*rcname != '/')
- X {
- X sprintf (dbuf, "%s/%s",ptr->pw_dir,rcname);
- X Newsrc = str_store (dbuf);
- X }
- X else
- X Newsrc = str_store (rcname);
- X if (*ccname != '/')
- X {
- X sprintf (dbuf, "%s/%s",ptr->pw_dir,ccname);
- X Ccfile = str_store (dbuf);
- X }
- X else
- X Ccfile = str_store (ccname);
- X sprintf (dbuf, "%s/%s%s",ptr->pw_dir,".vn","XXXXXX");
- X Onews = str_store (mktemp(dbuf));
- X if (access (Newsrc,0) != 0)
- X creat (Newsrc,0666);
- X
- X if (*keyxln != '/')
- X {
- X sprintf(dbuf, "%s/%s",ptr->pw_dir,keyxln);
- X set_kxln(dbuf);
- X }
- X else
- X set_kxln(keyxln);
- X}
- X
- Xstatic
- Xset_kxln(fname)
- Xchar *fname;
- X{
- X FILE *fp;
- X int i;
- X char bufr[80];
- X char in,out,*ptr;
- X char *index(), xln_str();
- X
- X for (i=0; i < 128; ++i)
- X Cxitop[i] = Cxitor[i] = Cxptoi[i] = Cxrtoi[i] = i;
- X
- X if ((fp = fopen(fname,"r")) != NULL)
- X {
- X while(fgets(bufr,79,fp) != NULL)
- X {
- X if (strncmp(bufr+1,"==",2) == 0)
- X ptr = bufr+2;
- X else
- X ptr = index(bufr+1,'=');
- X if (ptr == NULL)
- X continue;
- X *ptr = '\0';
- X ++ptr;
- X in = xln_str(bufr+1);
- X out = xln_str(ptr);
- X switch(bufr[0])
- X {
- X case 'r':
- X case 'R':
- X Cxrtoi[out] = in;
- X Cxitor[in] = out;
- X break;
- X case 'p':
- X case 'P':
- X Cxptoi[out] = in;
- X Cxitop[in] = out;
- X default:
- X break;
- X }
- X }
- X fclose(fp);
- X }
- X}
- X
- Xstatic char
- Xxln_str(s)
- Xchar *s;
- X{
- X if (*s < '0' || *s > '9')
- X return(*s & 0x7f);
- X return((char)(atoi(s) & 0x7f));
- X}
- @//E*O*F envir_set.c//
- if test 2931 -ne "`wc -c <'envir_set.c'`"; then
- echo shar: error transmitting "'envir_set.c'" '(should have been 2931 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'groupdir.c'" '(686 characters)'
- if test -f 'groupdir.c' ; then
- echo shar: will not over-write existing file "'groupdir.c'"
- else
- sed 's/^X//' >groupdir.c <<'@//E*O*F groupdir.c//'
- X/*
- X** vn news reader.
- X**
- X** groupdir.c - translation between newsgroup name and directory
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#include <stdio.h>
- X#include "config.h"
- X#include "vn.h"
- X
- Xextern PAGE Page;
- X
- X/*
- X g_dir converts newsgroup name to directory string
- X*/
- Xg_dir(s,t)
- Xchar *s,*t;
- X{
- X char *ptr, *index();
- X sprintf (t,"%s/%s",SPOOLDIR,s);
- X for (ptr=t+strlen(SPOOLDIR)+1; (ptr = index(ptr,'.')) != NULL; *ptr = '/')
- X ;
- X}
- X
- X
- X/*
- X change directory to group
- X*/
- Xcd_group ()
- X{
- X char dbuf [RECLEN];
- X g_dir ((Page.h.group)->nd_name,dbuf);
- X if (chdir(dbuf) < 0)
- X {
- X Page.h.artnum = 1;
- X Page.b[0].art_id = 0;
- X strcpy (Page.b[0].art_t, "CANNOT FIND NEWSGROUP");
- X }
- X}
- @//E*O*F groupdir.c//
- if test 686 -ne "`wc -c <'groupdir.c'`"; then
- echo shar: error transmitting "'groupdir.c'" '(should have been 686 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'hash.c'" '(1842 characters)'
- if test -f 'hash.c' ; then
- echo shar: will not over-write existing file "'hash.c'"
- else
- sed 's/^X//' >hash.c <<'@//E*O*F hash.c//'
- X/*
- X** vn news reader.
- X**
- X** hash.c - hash table routines
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#include <stdio.h>
- X#include "config.h"
- X#include "tune.h"
- X#include "vn.h"
- X
- X/*
- X** hash table manipulation routines:
- X** also sets Ncount, allocates Newsorsder array, and sets Newsorder
- X** initially to order newsgroups were entered in (active file order)
- X*/
- X
- Xextern int Ncount;
- Xextern NODE **Newsorder;
- X
- Xstatic NODE *Tab [HASHSIZE]; /* hash Table */
- X
- Xhashinit ()
- X{
- X int i;
- X for (i=0; i < HASHSIZE; ++i)
- X Tab[i] = NULL;
- X Ncount = 0;
- X}
- X
- X/*
- X enter new node (name s, articles n, low l) in hash Table,
- X initial flags = 0. As nodes are entered, pnum item is temporarily
- X used to indiacte entry order for initial construction of Newsorder
- X array via entry_order();
- X*/
- XNODE *hashenter(s,n,l)
- Xchar *s;
- Xint n;
- Xint l;
- X{
- X char *str_store();
- X NODE *ptr,*node_store();
- X int i;
- X
- X i=hash(s);
- X ptr = node_store();
- X ptr->next = Tab[i];
- X Tab[i] = ptr;
- X if (l > n)
- X l = n;
- X ptr->pnum = Ncount;
- X ++Ncount;
- X ptr->rdnum = l;
- X ptr->state = 0;
- X ptr->art = n;
- X ptr->nd_name = str_store(s);
- X return (ptr);
- X}
- X
- XNODE *hashfind(s)
- Xchar *s;
- X{
- X NODE *ptr;
- X
- X for (ptr = Tab[hash(s)]; ptr != NULL && strcmp(ptr->nd_name,s) != 0;
- X ptr = ptr->next)
- X ;
- X return (ptr);
- X}
- X
- X/*
- X** entry order is called after all hash_enter's have been done, PRIOR
- X** to the use of pnum item for anything else. It constructs the initial
- X** Newsorder array.
- X*/
- Xentry_order()
- X{
- X int i;
- X NODE *ptr;
- X
- X if ((Newsorder = (NODE **) malloc(Ncount*sizeof(NODE *))) == NULL)
- X printex("Cannot allocate memory for Newsorder array");
- X for (i=0; i < HASHSIZE; ++i)
- X {
- X for (ptr = Tab[i]; ptr != NULL; ptr = ptr->next)
- X Newsorder[ptr->pnum] = ptr;
- X }
- X}
- X
- Xstatic hash (s)
- Xchar *s;
- X{
- X int rem;
- X for (rem=0; *s != '\0'; ++s)
- X rem = (rem*128 + (*s&0x7f)) % HASHSIZE;
- X return (rem);
- X}
- @//E*O*F hash.c//
- if test 1842 -ne "`wc -c <'hash.c'`"; then
- echo shar: error transmitting "'hash.c'" '(should have been 1842 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'head.h'" '(839 characters)'
- if test -f 'head.h' ; then
- echo shar: will not over-write existing file "'head.h'"
- else
- sed 's/^X//' >head.h <<'@//E*O*F head.h//'
- X/*
- X** vn news reader.
- X**
- X** head.h - header line strings and lengths
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X/*
- X header lines and associated lengths. Strings should
- X actually be used once in strings.c.
- X*/
- X#define RHEAD "References: "
- X#define RHDLEN 12
- X#define MHEAD "Message-ID: "
- X#define MHDLEN 12
- X#define PHEAD "Path: "
- X#define PHDLEN 6
- X#define DHEAD "Date: "
- X#define DHDLEN 6
- X#define RTHEAD "Reply-To: "
- X#define RTHDLEN 10
- X#define TOHEAD "To: "
- X#define TOHDLEN 4
- X#define FHEAD "From: "
- X#define FHDLEN 6
- X#define FTHEAD "Followup-To: "
- X#define FTHDLEN 13
- X#define DISHEAD "Distribution: "
- X#define DISHDLEN 14
- X#define THEAD "Subject: "
- X#define THDLEN 9
- X#define LHEAD "Lines: "
- X#define LHDLEN 7
- X#define NHEAD "Newsgroups: "
- X#define NHDLEN 12
- X
- X#define CHFIRST "FSL" /* first char's of those used in page display */
- @//E*O*F head.h//
- if test 839 -ne "`wc -c <'head.h'`"; then
- echo shar: error transmitting "'head.h'" '(should have been 839 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'mf.nore'" '(254 characters)'
- if test -f 'mf.nore' ; then
- echo shar: will not over-write existing file "'mf.nore'"
- else
- sed 's/^X//' >mf.nore <<'@//E*O*F mf.nore//'
- XCFLAGS= -O -DJOBCONTROL
- XLIBS= -ltermcap
- X
- XOBJS= hash.o groupdir.o envir_set.o newsrc.o pagefile.o reader.o storage.o sig_set.o term_set.o tty_set.o userlist.o vn.o vnglob.o digest.o strings.o tmpnam.o reg.o strtok.o
- X
- Xvn: $(OBJS)
- X cc -o vn $(OBJS) $(LIBS)
- @//E*O*F mf.nore//
- if test 254 -ne "`wc -c <'mf.nore'`"; then
- echo shar: error transmitting "'mf.nore'" '(should have been 254 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'mf.re'" '(272 characters)'
- if test -f 'mf.re' ; then
- echo shar: will not over-write existing file "'mf.re'"
- else
- sed 's/^X//' >mf.re <<'@//E*O*F mf.re//'
- XCFLAGS= -O -Dregfree=free -DJOBCONTROL
- XREGLIB=
- XLIBS= -ltermcap
- X
- XOBJS= hash.o groupdir.o envir_set.o newsrc.o pagefile.o reader.o storage.o sig_set.o term_set.o tty_set.o userlist.o vn.o vnglob.o digest.o strings.o tmpnam.o
- X
- Xvn: $(OBJS)
- X cc -o vn $(OBJS) $(LIBS) $(REGLIB)
- @//E*O*F mf.re//
- if test 272 -ne "`wc -c <'mf.re'`"; then
- echo shar: error transmitting "'mf.re'" '(should have been 272 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'mf.sysv'" '(271 characters)'
- if test -f 'mf.sysv' ; then
- echo shar: will not over-write existing file "'mf.sysv'"
- else
- sed 's/^X//' >mf.sysv <<'@//E*O*F mf.sysv//'
- XCFLAGS= -O -Dregfree=free -Dindex=strchr -Drindex=strrchr -DSYSV
- XLIBS= -ltermcap
- X
- XOBJS= hash.o groupdir.o envir_set.o newsrc.o pagefile.o reader.o storage.o sig_set.o term_set.o tty_set.o userlist.o vn.o vnglob.o digest.o strings.o
- X
- Xvn: $(OBJS)
- X cc -o vn $(OBJS) $(LIBS)
- @//E*O*F mf.sysv//
- if test 271 -ne "`wc -c <'mf.sysv'`"; then
- echo shar: error transmitting "'mf.sysv'" '(should have been 271 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'newsrc.c'" '(11576 characters)'
- if test -f 'newsrc.c' ; then
- echo shar: will not over-write existing file "'newsrc.c'"
- else
- sed 's/^X//' >newsrc.c <<'@//E*O*F newsrc.c//'
- X/*
- X** vn news reader.
- X**
- X** newsrc.c - routines to deal with the newsrc file
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include "config.h"
- X#include "tty.h"
- X#include "vn.h"
- X
- Xextern NODE **Newsorder;
- Xextern char *Onews, *Newsrc;
- Xextern int Ncount, Lrec, C_allow;
- Xextern int Ntopt, Nntopt, Nwopt, Nnwopt;
- Xextern char *Topt[], *Negtopt[], *Wopt[], *Negwopt[];
- Xextern int Nounsub, Listfirst;
- X
- X/*
- X global flags signifying options set
- X*/
- X#define GF_ALL 1 /* -x option - scan everything */
- X#define GF_SPEC 2 /* -n option(s) - user specified groups */
- X#define GF_OVER 4 /* command line specification - overide marks */
- X
- Xstatic char *Options[OPTLINES];
- Xstatic int New_idx, Max_name, Optlines;
- Xstatic unsigned Gflags = 0;
- X
- X/*
- X routines for dealing with the .newsrc file and options
- X*/
- X
- X/*
- X command name argument is already omitted from argv argc in this
- X routine. Only the option arguments are present. We process
- X options before we scan the rest of .newsrc, which redoes Newsorder,
- X ie. we don't clobber Ncount until options are processed.
- X*/
- Xscan_newsrc (argc,argv)
- Xint argc;
- Xchar **argv;
- X{
- X FILE *fp, *fopen();
- X static char marks[] =
- X {
- X NEWS_ON, NEWS_OFF, '\0'
- X };
- X char *str_store ();
- X int line, len, num;
- X char buf [RECLEN], trail, optpflag, submark, *fret, *ptr, *strpbrk(), *strtok();
- X
- X
- X /* initialize hash table, open temp file, fill table with active articles */
- X hashinit ();
- X fill_active ();
- X temp_open();
- X
- X if (argc > 0)
- X {
- X Gflags |= GF_OVER;
- X arg_opt(argc,argv);
- X optpflag = 'y';
- X }
- X else
- X optpflag = 'n';
- X
- X if ((fp = fopen (Newsrc,"r")) == NULL)
- X printex ("can't open %s for reading",Newsrc);
- X
- X Optlines = 0;
- X
- X for (line = 1; (fret = fgets(buf,RECLEN-1,fp)) != NULL && emptyline(buf) == 1; ++line)
- X ;
- X if (fret != NULL && strncmp (buf,"options",7) == 0)
- X {
- X Options[0] = str_store(buf);
- X Optlines = 1;
- X trail = buf [strlen(buf)-2];
- X for ( ; (fret = fgets(buf,RECLEN-1,fp)) != NULL; ++line)
- X {
- X if (trail != '\\' && buf[0] != ' ' && buf[0] != '\t')
- X break;
- X if (Optlines >= OPTLINES)
- X printex ("%s - too many option lines (%d allowed)",Newsrc,OPTLINES);
- X Options[Optlines] = str_store(buf);
- X ++Optlines;
- X if ((len = strlen(buf)) >= 2 && buf[len-2] != '\\')
- X trail = buf[len-2];
- X else
- X trail = '\0';
- X }
- X }
- X
- X /* do the options from the newsrc file if there weren't command line args */
- X if (Optlines > 0 && optpflag == 'n')
- X newsrc_opt ();
- X
- X Ncount = 0;
- X
- X for ( ; fret != NULL; ++line, fret = fgets(buf,RECLEN-1,fp))
- X {
- X if (emptyline(buf) == 1)
- X continue;
- X if ((ptr = strpbrk(buf,marks)) == NULL)
- X {
- X fprintf (stderr,"\nwarning: line %d of %s (%s) - bad syntax\n",
- X line,Newsrc,buf);
- X continue;
- X }
- X submark = *ptr;
- X *ptr = '\0';
- X ++ptr;
- X num = 0;
- X for (ptr = strtok(ptr," ,-\n"); ptr != NULL; ptr = strtok(NULL," ,-\n"))
- X {
- X len = atoi (ptr);
- X for ( ; *ptr >= '0' && *ptr <= '9'; ++ptr)
- X ;
- X if (*ptr != '\0' || len < num)
- X {
- X num = -1;
- X fprintf (stderr,"\nwarning: line %d of %s (%s) - bad syntax\n",
- X line,Newsrc,buf);
- X break;
- X }
- X num = len;
- X }
- X if (num < 0)
- X continue;
- X chkgroup (buf,submark,num);
- X }
- X fclose (fp);
- X
- X /* now take care of groups not specified in .newsrc */
- X art_active();
- X
- X /* free up the option string storage */
- X for (num=0; num < Ntopt; ++num)
- X regfree (Topt[num]);
- X for (num=0; num < Nwopt; ++num)
- X regfree (Wopt[num]);
- X for (num=0; num < Nntopt; ++num)
- X regfree (Negtopt[num]);
- X for (num=0; num < Nnwopt; ++num)
- X regfree (Negwopt[num]);
- X Ntopt = Nwopt = Nntopt = Nnwopt = 0;
- X}
- X
- Xstatic emptyline(s)
- Xchar *s;
- X{
- X while (isspace(*s))
- X ++s;
- X if (*s == '\0')
- X return (1);
- X return (0);
- X}
- X
- X/*
- X fill hash table from active news group list
- X temporarily makes "Newsorder" active list order.
- X This is needed to be able to process options
- X before scanning user order.
- X*/
- Xstatic fill_active ()
- X{
- X FILE *f,*fopen ();
- X char *nread, act_rec[RECLEN], *strtok();
- X int num,lownum;
- X
- X Max_name = 0;
- X if ((f = fopen (ACTFILE,"r")) == NULL)
- X printex ("couldn't open %s\n",ACTFILE);
- X while (fgets(act_rec, RECLEN-1, f) != NULL)
- X {
- X if (strtok (act_rec," \n") == NULL)
- X continue;
- X nread = strtok (NULL, " \n");
- X if (nread != NULL)
- X num = atoi(nread);
- X else
- X num = 0;
- X nread = strtok (NULL, " \n");
- X if (nread != NULL)
- X lownum = atoi(nread);
- X else
- X lownum = 0;
- X if (lownum > 0)
- X --lownum;
- X if (strlen(act_rec) > Max_name)
- X Max_name = strlen(act_rec);
- X hashenter (act_rec, num, lownum);
- X }
- X
- X /* construct initial Newsorder */
- X entry_order();
- X
- X fclose (f);
- X}
- X
- X/*
- X check active newsgroups not mentioned in NEWSRC file
- X (FLG_SCAN not set)
- X*/
- Xstatic art_active ()
- X{
- X char act_rec[RECLEN], *strtok();
- X NODE *ptr,*hashfind();
- X FILE *f,*fopen();
- X if ((f = fopen (ACTFILE,"r")) == NULL)
- X printex ("couldn't open %s\n",ACTFILE);
- X New_idx = Ncount;
- X while (fgets(act_rec, RECLEN-1, f) != NULL)
- X {
- X if (strtok (act_rec," \n") == NULL)
- X continue;
- X if ((ptr = hashfind (act_rec)) == NULL)
- X printex("%s - unexpected hash table failure",act_rec);
- X if ((ptr->state & FLG_SCAN) == 0)
- X chkgroup (ptr->nd_name, NEWS_ON, 0);
- X }
- X}
- X
- X/*
- X check group for new articles:
- X s - group
- X c - subscription indicator from NEWSRC
- X n - number read
- X*/
- Xstatic chkgroup (s,c,n)
- Xchar *s,c;
- Xint n;
- X{
- X NODE *ptr, *hashfind();
- X int lold,lowart;
- X lold = Lrec;
- X if ((ptr = hashfind(s)) != NULL && (ptr->state & FLG_SCAN) == 0)
- X {
- X Newsorder [Ncount] = ptr;
- X ++Ncount;
- X ptr->pages = 0;
- X ptr->state |= FLG_SCAN;
- X if (c == NEWS_ON)
- X ptr->state |= FLG_SUB;
- X /* if "read" more than exist reset to zero */
- X if (n > ptr->art)
- X n = 0;
- X lowart = ptr->rdnum;
- X if (n < ptr->rdnum)
- X n = ptr->rdnum;
- X ptr->orgrd = ptr->pgrd = ptr->rdnum = n;
- X ptr->pgshwn = 0L;
- X
- X /*
- X ** scan decision is rather complex, since GF_ALL setting
- X ** overides "n" value, GF_SPEC indicates FLG_SPEC flag used.
- X ** if GF_OVER set, FLG_SPEC overides subscription mark, else
- X ** FLG_SPEC AND subscribed is neccesary.
- X */
- X if ((Gflags & GF_SPEC) != 0)
- X {
- X if ((ptr->state & FLG_SPEC) == 0)
- X c = NEWS_OFF;
- X else
- X {
- X if ((Gflags & GF_OVER) != 0)
- X c = NEWS_ON;
- X }
- X }
- X if ((Gflags & GF_ALL) != 0)
- X n = lowart;
- X if (c == NEWS_ON && ptr->art > n)
- X {
- X outgroup (s,n,ptr->art);
- X if (lold != Lrec)
- X {
- X ptr->pnum = lold+1;
- X ptr->pages = Lrec - lold;
- X ptr->state |= FLG_PAGE;
- X }
- X }
- X }
- X}
- X
- X/*
- X wr_newsrc writes the .newsrc file
- X*/
- Xwr_newsrc ()
- X{
- X FILE *fp,*fopen();
- X NODE *p;
- X char c;
- X int i,rc;
- X
- X if (link(Newsrc,Onews) < 0)
- X printex ("can't backup %s to %s before writing",Newsrc,Onews);
- X
- X if (unlink(Newsrc) < 0 || (fp = fopen(Newsrc,"w")) == NULL)
- X printex ("can't open %s for writing (backed up in %s)",Newsrc,Onews);
- X else
- X {
- X clearerr(fp);
- X for (i=0; (rc = ferror(fp)) == 0 && i < Optlines; ++i)
- X fprintf (fp,"%s",Options[i]);
- X for (i=0; rc == 0 && i < Ncount; ++i)
- X {
- X p = Newsorder[i];
- X if ((p->state & FLG_SUB) == 0)
- X c = NEWS_OFF;
- X else
- X c = NEWS_ON;
- X#ifdef OLDRC
- X fprintf (fp,"%s%c %d\n",p->nd_name,c,p->rdnum);
- X#else
- X if (p->rdnum > 0)
- X fprintf (fp,"%s%c 1-%d\n",p->nd_name,c,p->rdnum);
- X else
- X fprintf (fp,"%s%c 0\n",p->nd_name,c);
- X#endif
- X rc = ferror(fp);
- X }
- X fclose (fp);
- X if (rc != 0)
- X printex ("write of %s failed, old copy stored in %s",Newsrc,Onews);
- X else
- X unlink (Onews);
- X }
- X}
- X
- Xnew_groups ()
- X{
- X int i,wrem,w;
- X char fs[24],c_end;
- X if (New_idx >= Ncount || C_allow < (w = Max_name+1))
- X return (0);
- X term_set (ERASE);
- X printf (NEWGFORM,Newsrc);
- X sprintf (fs,"%%-%ds%%c",Max_name);
- X wrem = C_allow;
- X for (i=New_idx; i < Ncount; ++i)
- X {
- X if ((wrem -= w) < w)
- X {
- X wrem = C_allow;
- X c_end = '\n';
- X }
- X else
- X c_end = ' ';
- X printf (fs,(Newsorder[i])->nd_name,c_end);
- X }
- X if ((++wrem) < C_allow)
- X putchar ('\n');
- X return (i-New_idx);
- X}
- X
- X/*
- X arg_opt must be called prior to option scanning, since
- X it uses the options array. This is a bit of a kludge,
- X but it saves a bunch of work. NOTE - no command name argument
- X*/
- Xstatic arg_opt (argc,argv)
- Xint argc;
- Xchar **argv;
- X{
- X if (argc > OPTLINES)
- X printex ("too many command line options (%d allowed)\n",OPTLINES);
- X for (Optlines=0; Optlines < argc; ++Optlines)
- X {
- X Options[Optlines] = *argv;
- X ++argv;
- X }
- X newsrc_opt();
- X}
- X
- X/*
- X option setting routine:
- X sets global flags: GF_ALL for -x option GF_SPEC for -n.
- X sets up filter array for article scanning
- X*/
- Xstatic newsrc_opt()
- X{
- X int i;
- X char curopt,tmp[RECLEN],*tok,*strtok(),*index();
- X
- X Nounsub = Listfirst = 0;
- X Ntopt = Nwopt = Nnwopt = Nntopt = 0;
- X curopt = '\0';
- X for (i=0; i < Optlines; ++i)
- X {
- X strcpy(tmp,Options[i]);
- X for (tok = strtok(tmp,",\\ \t\n"); tok != NULL; tok = strtok(NULL,",\\ \t\n"))
- X {
- X if (*tok != '-')
- X do_opt (curopt,tok);
- X else
- X {
- X for (++tok; index("nwt",*tok) == NULL; ++tok)
- X {
- X /* options with no strings */
- X switch(*tok)
- X {
- X case 'S':
- X Gflags &= ~GF_OVER;
- X break;
- X case '%':
- X Listfirst = 1;
- X break;
- X case 'U':
- X Nounsub = 1;
- X break;
- X#ifdef OLDRC
- X case 'i':
- X /* Treat "-i" as synonym for "-x" */
- X#endif
- X case 'x':
- X Gflags |= GF_ALL;
- X default:
- X break;
- X }
- X }
- X curopt = *tok;
- X if (*(++tok) != '\0')
- X do_opt (curopt,tok);
- X }
- X }
- X }
- X}
- X
- X/* do_opt is for options with strings attached */
- Xstatic do_opt (opt,str)
- Xchar opt, *str;
- X{
- X switch (opt)
- X {
- X case 'n':
- X Gflags |= GF_SPEC;
- X specmark(str);
- X break;
- X case 'w':
- X specfilter (FIL_AUTHOR,str);
- X break;
- X case 't':
- X specfilter (FIL_TITLE,str);
- X break;
- X default:
- X#ifdef OLDRC
- X Gflags |= GF_SPEC; /* Assume anything else is newsgroup */
- X specmark(str);
- X#endif
- X break;
- X }
- X}
- X
- Xstatic specfilter (comp,str)
- Xchar comp,*str;
- X{
- X char *regcmp();
- X int *count;
- X char **rex;
- X
- X /*
- X ** we may set rex one past end of array. we will error before
- X ** referencing it if that's the case, however.
- X */
- X if (*str == '!')
- X {
- X if (comp == FIL_TITLE)
- X {
- X count = &Nntopt;
- X rex = Negtopt + *count;
- X }
- X else
- X {
- X count = &Nnwopt;
- X rex = Negwopt + *count;
- X }
- X ++str;
- X }
- X else
- X {
- X if (comp == FIL_TITLE)
- X {
- X count = &Ntopt;
- X rex = Topt + *count;
- X }
- X else
- X {
- X count = &Nwopt;
- X rex = Wopt + *count;
- X }
- X }
- X if (*count >= NUMFILTER)
- X printex ("too many %c options, %d allowed",comp,NUMFILTER);
- X if ((*rex = regcmp(str,(char *) 0)) == NULL)
- X printex ("%c option regular expression syntax: %s",comp,str);
- X ++(*count);
- X}
- X
- X/*
- X handle the newsgroup specification string.
- X ("all" convention - braack!!!)
- X*/
- Xstatic specmark (s)
- Xchar *s;
- X{
- X unsigned ormask,andmask;
- X int i,len;
- X char *ptr,*re,pattern[RECLEN],*regex(),*regcmp();
- X
- X if (*s == '!')
- X {
- X ++s;
- X ormask = 0;
- X andmask = ~FLG_SPEC;
- X if (*s == '\0')
- X return;
- X }
- X else
- X {
- X ormask = FLG_SPEC;
- X andmask = 0xffff;
- X }
- X
- X /* convert "all" not bounded by alphanumerics to ".*". ".all" becomes ".*" */
- X for (ptr = s; (len = findall(ptr)) >= 0; ptr += len+1)
- X {
- X if (len > 0 && isalnum (s[len-1]))
- X continue;
- X if (isalnum (s[len+3]))
- X continue;
- X if (len > 0 && s[len-1] == '.')
- X {
- X --len;
- X strcpy (s+len,s+len+1);
- X }
- X s[len] = '.';
- X s[len+1] = '*';
- X strcpy (s+len+2,s+len+3);
- X }
- X
- X /* now use regular expressions */
- X sprintf (pattern,"^%s$",s);
- X if ((re = regcmp(pattern,(char *) 0)) == NULL)
- X printex ("n option regular expression syntax: %s",s);
- X for (i=0; i < Ncount; ++i)
- X {
- X if (regex(re,(Newsorder[i])->nd_name) != NULL)
- X {
- X (Newsorder[i])->state |= ormask;
- X (Newsorder[i])->state &= andmask;
- X }
- X }
- X regfree (re);
- X}
- X
- Xstatic findall (s)
- Xchar *s;
- X{
- X int len;
- X for (len=0; *s != '\0'; ++s,++len)
- X {
- X if (*s == 'a' && strncmp(s,"all",3) == 0)
- X return (len);
- X }
- X return (-1);
- X}
- @//E*O*F newsrc.c//
- if test 11576 -ne "`wc -c <'newsrc.c'`"; then
- echo shar: error transmitting "'newsrc.c'" '(should have been 11576 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'pagefile.c'" '(5053 characters)'
- if test -f 'pagefile.c' ; then
- echo shar: will not over-write existing file "'pagefile.c'"
- else
- sed 's/^X//' >pagefile.c <<'@//E*O*F pagefile.c//'
- X/*
- X** vn news reader.
- X**
- X** pagefile.c - routines to deal with page display tempfile
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#include <stdio.h>
- X
- X#ifdef SYSV
- X#include <sys/types.h>
- X#include <fcntl.h>
- X#endif
- X
- X#include <sys/file.h>
- X#include "vn.h"
- X#include "head.h"
- X
- Xextern int Ncount,Lrec,L_allow,Cur_page,C_allow;
- Xextern int Nwopt, Nnwopt, Ntopt, Nntopt;
- Xextern char *Wopt[], *Topt[], *Negtopt[], *Negwopt[];
- Xextern NODE **Newsorder;
- Xextern PAGE Page;
- Xextern int Digest;
- X
- Xextern char *Aformat;
- X
- Xextern char *T_head, *F_head, *L_head;
- X
- Xstatic int Tdes; /* temp file descriptor */
- Xstatic int Pgsize; /* block size for seeking file */
- X
- X/*
- X routines which deal with the temp file containing
- X display pages. Note the "invisible" file feature -
- X tempfile is unlinked from /usr/tmp immediately. when
- X Tdes is closed by UNIX the disk space will be given back.
- X*/
- X
- Xtemp_open ()
- X{
- X char tmpart [L_tmpnam];
- X Lrec = -1;
- X tmpnam (tmpart);
- X Pgsize = sizeof (HEAD) + L_allow * sizeof(BODY);
- X if ((Tdes = open(tmpart,O_RDWR|O_CREAT)) < 0)
- X printex ("can't open %s",tmpart);
- X unlink (tmpart);
- X}
- X
- X/*
- X create page records for newsgroup s
- X all articles between low and hi are to be included.
- X*/
- Xoutgroup (s,low,hi)
- Xchar *s;
- Xint low,hi;
- X{
- X int i,aid;
- X char title[RECLEN],gd[RECLEN];
- X g_dir(s,gd);
- X if (chdir(gd) < 0)
- X {
- X grp_indic(s,0);
- X return;
- X }
- X grp_indic(s,1);
- X aid = 0;
- X for (i=low+1; i <= hi; ++i)
- X {
- X if (digname (i,title) >= 0)
- X {
- X Page.b[aid].art_id = i;
- X Page.b[aid].art_mark = ' ';
- X strcpy (Page.b[aid].art_t, title);
- X if ((++aid) >= L_allow)
- X {
- X
- X /* start next page */
- X Page.h.artnum = L_allow;
- X do_write ();
- X ++Lrec;
- X aid = 0;
- X }
- X }
- X }
- X
- X /* last page (partial) */
- X if (aid != 0)
- X {
- X Page.h.artnum = aid;
- X do_write ();
- X ++Lrec;
- X }
- X}
- X
- X/*
- X set current page to n. use Pgsize and lseek to find it in
- X temp file (descriptor Tdes).
- X*/
- Xfind_page (n)
- Xint n;
- X{
- X long off,lseek();
- X int i,last;
- X Cur_page = n;
- X off = Pgsize;
- X off *= (long) n;
- X lseek (Tdes, off, 0);
- X if (read(Tdes, (char *) &(Page.h), sizeof(HEAD)) < sizeof(HEAD))
- X printex("bad temp file read");
- X i = Pgsize - sizeof(HEAD);
- X if (read(Tdes, (char *) Page.b, i) < i)
- X printex("bad temp file read");
- X last = -1;
- X for (i=0; i < Ncount; ++i)
- X {
- X if ((Newsorder[i])->pages > 0)
- X {
- X if ((Newsorder[i])->pnum > n)
- X break;
- X last = i;
- X }
- X }
- X if (last < 0)
- X printex ("can't find page %d",n);
- X Page.h.group = Newsorder[last];
- X Page.h.name = (Page.h.group)->nd_name;
- X cd_group ();
- X}
- X
- Xwrite_page ()
- X{
- X long off,lseek();
- X if (!Digest)
- X {
- X off = Pgsize;
- X off *= (long) Cur_page;
- X lseek (Tdes, off, 0);
- X do_write();
- X }
- X}
- X
- Xstatic do_write()
- X{
- X int num;
- X
- X if (write(Tdes, (char *) &(Page.h), sizeof(HEAD)) < sizeof(HEAD))
- X printex ("Bad temp file write");
- X num = L_allow * sizeof(BODY);
- X if (write(Tdes, (char *) Page.b, num) < num)
- X printex ("Bad temp file write");
- X}
- X
- X/*
- X find article title:
- X n - articles id
- X t - returned title - must have storage for RECLEN, assumed to be
- X > 3 * max title length also.
- X*/
- Xstatic digname (n, t)
- Xint n;
- Xchar *t;
- X{
- X int i,j;
- X FILE *fp,*fopen();
- X char ff [MAX_C+1],fn [MAX_C+1],fl [MAX_C+1],*index();
- X
- X /* open article */
- X sprintf (t,"%d", n);
- X if ((fp = fopen(t,"r")) == NULL)
- X return (-1);
- X
- X /* get subject, from and lines by reading article */
- X ff[0] = fn[0] = fl[0] = '?';
- X ff[1] = fn[1] = fl[1] = '\0';
- X ff[C_allow] = fn[C_allow] = fl[C_allow] = '\0';
- X for (i = 0; i < HDR_LINES && fgets(t,RECLEN-1,fp) != NULL; ++i)
- X {
- X if (index(CHFIRST,t[0]) == NULL)
- X continue;
- X t[strlen(t) - 1] = '\0';
- X if (strncmp(T_head,t,THDLEN) == 0)
- X {
- X for (j=0; j < Nntopt; ++j)
- X {
- X if (regex(Negtopt[j],t+THDLEN) != NULL)
- X {
- X fclose(fp);
- X return(-1);
- X }
- X }
- X if (Ntopt > 0)
- X {
- X for (j=0; j < Ntopt; ++j)
- X {
- X if (regex(Topt[j],t+THDLEN) != NULL)
- X break;
- X }
- X if (j >= Ntopt)
- X {
- X fclose(fp);
- X return(-1);
- X }
- X }
- X strncpy(fn,t+THDLEN,C_allow);
- X continue;
- X }
- X if (strncmp(F_head,t,FHDLEN) == 0)
- X {
- X for (j=0; j < Nnwopt; ++j)
- X {
- X if (regex(Negwopt[j],t+FHDLEN) != NULL)
- X {
- X fclose(fp);
- X return(-1);
- X }
- X }
- X if (Nwopt > 0)
- X {
- X for (j=0; j < Nwopt; ++j)
- X {
- X if (regex(Wopt[j],t+FHDLEN) != NULL)
- X break;
- X }
- X if (j >= Nwopt)
- X {
- X fclose(fp);
- X return(-1);
- X }
- X }
- X strncpy(ff,t+FHDLEN,C_allow);
- X continue;
- X }
- X if (strncmp(L_head,t,LHDLEN) == 0)
- X {
- X strncpy(fl,t+LHDLEN,C_allow);
- X break;
- X }
- X }
- X
- X fclose (fp);
- X
- X /* reject empty or 1 line files */
- X if (i < 2)
- X return (-1);
- X
- X form_title (t,fn,fl,ff,n);
- X return (0);
- X}
- X
- Xform_title (t,fn,fl,ff,n)
- Xchar *t,*fn,*fl,*ff;
- Xint n;
- X{
- X char *ptr,*index();
- X int i;
- X
- X if ((ptr = index(ff,'(')) != NULL && strlen(ptr) > 3)
- X ff = ptr;
- X sprintf (t,TFORMAT,fn,fl,ff);
- X sprintf(ff,Aformat,' ',' ',n);
- X i = C_allow - strlen(ff) + 1; /* remember newline in Aformat */
- X t[i] = '\0';
- X ctl_xlt(t);
- X return (0);
- X}
- X
- X/* replace control characters in titles */
- Xstatic ctl_xlt(s)
- Xchar *s;
- X{
- X while (*s != '\0')
- X {
- X if (*s < ' ')
- X *s += 'A' - 1;
- X ++s;
- X }
- X}
- @//E*O*F pagefile.c//
- if test 5053 -ne "`wc -c <'pagefile.c'`"; then
- echo shar: error transmitting "'pagefile.c'" '(should have been 5053 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'reader.h'" '(1498 characters)'
- if test -f 'reader.h' ; then
- echo shar: will not over-write existing file "'reader.h'"
- else
- sed 's/^X//' >reader.h <<'@//E*O*F reader.h//'
- X/*
- X** vn news reader.
- X**
- X** reader.h - article reading interface definitions
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#define PAGE_MID ":more (%2d%%):"
- X#define PAGE_NEXT ":next article:"
- X#define PAGE_END ":end:"
- X#define PAGE_NO ":?:"
- X#define PPR_MAX 18 /* maximum length of PAGE prompts */
- X
- X/*
- X reading commands: no control chars, add help message to helppg
- X SAVE, PRINT, HEADTOG and SETROT are also recognized
- X*/
- X#define HPG_HEAD "toggle header print flag"
- X#define HPG_ROT "toggle rotation"
- X#define HPG_SAVE "save article in a file"
- X#define HPG_PRINT "print article"
- X#define PG_NEXT 'n'
- X#define HPG_NEXT "next article, if any"
- X#define PG_QUIT 'q'
- X#define HPG_QUIT "quit reading articles, if any more to read"
- X#define PG_FLIP 'Q'
- X#define HPG_FLIP "quit reading, and turn to next page of articles"
- X#define PG_FOLLOW 'f'
- X#define HPG_FOLLOW "post followup to article"
- X#define PG_REPLY 'm'
- X#define HPG_REPLY "send mail to author of article"
- X#define PG_HELP '?'
- X#define HPG_HELP "see this help menu"
- X#define PG_REWIND 'r'
- X#define HPG_REWIND "rewind article to beginning"
- X#define PG_WIND 'e'
- X#define HPG_WIND "seek to end of article (to next/end prompt)"
- X#define PG_STEP '\n'
- X#define HPG_STEP "next line"
- X#define PG_SEARCH '/'
- X#define HPG_SEARCH "search for regular expression in remainder of article"
- X#define SEARCHFORM "search pattern (%s) ? "
- X#define HPG_DEF "\n anything else to continue normal reading"
- X#define HPG_EDEF "\n anything else to try reading next article, if any"
- @//E*O*F reader.h//
- if test 1498 -ne "`wc -c <'reader.h'`"; then
- echo shar: error transmitting "'reader.h'" '(should have been 1498 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'reg.c'" '(1656 characters)'
- if test -f 'reg.c' ; then
- echo shar: will not over-write existing file "'reg.c'"
- else
- sed 's/^X//' >reg.c <<'@//E*O*F reg.c//'
- X/*
- X** vn news reader.
- X**
- X** reg.c - implementation of regex / regcmp on top of UCB library
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#include <stdio.h>
- X
- X#define RGBLKSIZE 20
- X
- Xstruct _regtab
- X{
- X struct _regtab *link;
- X char *regstr;
- X};
- X
- Xtypedef struct _regtab REGTAB;
- X
- Xstatic REGTAB *Chain = NULL;
- Xstatic REGTAB *Free = NULL;
- Xstatic REGTAB *Compiled = NULL;
- X
- Xregfree(s)
- Xchar *s;
- X{
- X REGTAB *ptr,*cmp,*old;
- X
- X cmp = (REGTAB *) s;
- X old = NULL;
- X
- X for (ptr = Chain; ptr != NULL; ptr = (old = ptr)->link)
- X {
- X if (ptr == cmp)
- X {
- X if (old == NULL)
- X Chain = Chain->link;
- X else
- X old->link = ptr->link;
- X ptr->link = Free;
- X Free = ptr;
- X break;
- X }
- X }
- X}
- X
- Xchar *regcmp(str)
- Xchar *str;
- X{
- X int i;
- X char *str_store();
- X char *re_comp();
- X
- X if (re_comp(str) != NULL)
- X {
- X Compiled = NULL; /* make sure we're OK */
- X return(NULL);
- X }
- X
- X if (Free == NULL)
- X {
- X Free = (REGTAB *) malloc(RGBLKSIZE * sizeof(REGTAB));
- X if (Free == NULL)
- X printex ("regcmp: memory allocation failure");
- X for (i = 0; i < RGBLKSIZE - 1; ++i)
- X Free[i].link = Free + i + 1;
- X Free[i].link = NULL;
- X }
- X
- X Compiled = Free;
- X Free = Free->link;
- X
- X Compiled->link = Chain;
- X Chain = Compiled;
- X Compiled->regstr = str_store(str);
- X
- X return ((char *) Compiled);
- X}
- X
- Xchar *regex(reg,str)
- Xchar *reg,*str;
- X{
- X REGTAB *cmp;
- X
- X cmp = (REGTAB *) reg;
- X
- X if (cmp == Compiled)
- X {
- X if (re_exec(str))
- X return(str);
- X return (NULL);
- X }
- X
- X for (Compiled = Chain; Compiled != NULL; Compiled = Compiled->link)
- X {
- X if (Compiled == cmp)
- X break;
- X }
- X
- X if (Compiled == NULL)
- X printex ("regex: bad pointer");
- X
- X re_comp(Compiled->regstr);
- X
- X if (re_exec(str))
- X return(str);
- X
- X return(NULL);
- X}
- @//E*O*F reg.c//
- if test 1656 -ne "`wc -c <'reg.c'`"; then
- echo shar: error transmitting "'reg.c'" '(should have been 1656 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'sig_set.c'" '(4501 characters)'
- if test -f 'sig_set.c' ; then
- echo shar: will not over-write existing file "'sig_set.c'"
- else
- sed 's/^X//' >sig_set.c <<'@//E*O*F sig_set.c//'
- X/*
- X** vn news reader.
- X**
- X** sig_set.c - signal handler
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#include <stdio.h>
- X#include <sys/signal.h>
- X#include <sgtty.h>
- X#include <setjmp.h>
- X#include "tty.h"
- X#include "vn.h"
- X#include "config.h"
- X
- Xextern int L_allow;
- Xextern char *Version;
- X
- Xstatic int Sigflag=BRK_INIT; /* phase of interaction */
- Xstatic FILE **Fpseek; /* article reading file pointer pointer */
- Xstatic int Foreground;
- Xstatic jmp_buf Jumploc; /* for BRK_SESS phase */
- Xstatic char *Cur_scn; /* current group name being scanned */
- X
- X/*
- X interrupt handler - unusual termination (longjmp and printex aborts)
- X if not abort, remember to reset signal trap
- X CAUTION - the passing of a jump buffer is a little dicey - assumes
- X type jump_buf is an array.
- X
- X sigcatch and sig_set control a lot of i/o on stderr also, since
- X it is so intimately related to signal interaction. Note that the
- X SIGTSTP action causes a "stopped on tty output" if raw terminal
- X mode is restored by tty_set(RESTORE). We don't get it if we were
- X already cooked since tty_set avoids calling ioctl if it doesn't
- X have to.
- X*/
- Xstatic sigcatch (sig)
- Xint sig;
- X{
- X char buf [MAX_C+1];
- X int pgrp;
- X
- X /* disable signal while processing it */
- X signal (sig,SIG_IGN);
- X
- X switch (sig)
- X {
- X case SIGINT:
- X case SIGQUIT:
- X break;
- X
- X#ifdef JOBCONTROL
- X case SIGTSTP:
- X /* ignore SIGTTOU so we don't get stopped if [kc]sh grabs the tty */
- X signal(SIGTTOU, SIG_IGN);
- X tty_set (SAVEMODE);
- X term_set (MOVE,0,L_allow+RECBIAS-1);
- X printf ("\n");
- X Foreground = 0;
- X fflush (stdout);
- X fflush (stderr);
- X signal(SIGTTOU, SIG_DFL);
- X
- X /* Send the TSTP signal to suspend our process group */
- X signal(SIGTSTP, SIG_DFL);
- X sigsetmask(0);
- X kill (0, SIGTSTP);
- X
- X /* WE ARE NOW STOPPED */
- X
- X /*
- X WELCOME BACK!
- X if terminals process group is ours, we are foregrounded again
- X and can turn newsgroup name printing back on
- X */
- X tty_set (RESTORE);
- X switch (Sigflag)
- X {
- X case BRK_SESS:
- X signal (SIGTSTP,sigcatch);
- X longjmp (Jumploc,1);
- X case BRK_IN:
- X ioctl (1,TIOCGPGRP,&pgrp);
- X if (pgrp == getpgrp(0))
- X {
- X Foreground = 1;
- X if (Cur_scn != NULL)
- X fgprintf (" %s\n",Cur_scn);
- X }
- X break;
- X default:
- X break;
- X }
- X signal (SIGTSTP,sigcatch);
- X return;
- X#endif
- X default:
- X printex (BRK_MSG,sig);
- X }
- X
- X /* QUIT and INTERRUPT signals */
- X switch (Sigflag)
- X {
- X case BRK_SESS:
- X /* if in session, ask if really a quit, do longjump if not */
- X term_set (ERASE);
- X tty_set (RAWMODE);
- X user_str (buf, BRK_PR, 1);
- X if (buf[0] == 'y')
- X printex (BRK_MSG,sig);
- X signal (sig,sigcatch);
- X longjmp (Jumploc,1);
- X case BRK_READ:
- X /* if reading seek file to end to abort page printing */
- X printf ("\n");
- X if (*Fpseek == NULL || fseek(*Fpseek,0L,2) < 0)
- X putchar ('\07');
- X break;
- X default:
- X printex (BRK_MSG,sig);
- X }
- X signal (sig,sigcatch);
- X}
- X
- X/*
- X sig_set controls what will be done with a signal when picked up by
- X sigcatch. grp_indic / fgprintf is included here to keep knowledge
- X of TSTP state localized.
- X*/
- X/* VARARGS */
- Xsig_set (flag,dat)
- Xint flag, *dat;
- X{
- X int i, *xfer, pgrp;
- X if (Sigflag == BRK_INIT)
- X {
- X Cur_scn = NULL;
- X signal (SIGINT,sigcatch);
- X signal (SIGQUIT,sigcatch);
- X signal (SIGHUP,sigcatch);
- X signal (SIGTERM,sigcatch);
- X#ifdef JOBCONTROL
- X signal (SIGTSTP,sigcatch);
- X ioctl (1,TIOCGPGRP,&pgrp);
- X if (pgrp == getpgrp(0))
- X {
- X Foreground = 1;
- X fgprintf ("Visual News, Release %s, reading:\n",Version);
- X }
- X else
- X Foreground = 0;
- X#else
- X Foreground = NOJOB_FG;
- X#endif
- X }
- X switch (flag)
- X {
- X case BRK_IN:
- X case BRK_OUT:
- X Sigflag = flag;
- X break;
- X case BRK_READ:
- X if (Sigflag != BRK_SESS)
- X printex ("unexpected read state, sig_set\n");
- X Fpseek = (FILE **) dat;
- X Sigflag = BRK_READ;
- X break;
- X case BRK_SESS:
- X xfer = (int *) Jumploc;
- X for (i=0; i < sizeof(Jumploc) / sizeof(int); ++i)
- X xfer[i] = dat[i];
- X Sigflag = BRK_SESS;
- X break;
- X case BRK_RFIN:
- X if (Sigflag != BRK_READ)
- X printex ("unexpected finish state, sig_set\n");
- X Sigflag = BRK_SESS;
- X break;
- X default:
- X printex ("bad state %d, sig_set\n",flag);
- X }
- X}
- X
- Xgrp_indic (s,ok)
- Xchar *s;
- Xint ok;
- X{
- X NODE *ptr,*hashfind();
- X
- X /* we go to hash table because s might be a temporary buffer */
- X if ((ptr = hashfind(s)) != NULL)
- X {
- X Cur_scn = ptr->nd_name;
- X if (Foreground)
- X {
- X if (ok)
- X fgprintf(" %s\n",Cur_scn);
- X else
- X fgprintf(" %s - Can't access spool directory\n",Cur_scn);
- X }
- X }
- X}
- X
- Xfgprintf (fs,a,b,c,d,e)
- Xchar *fs;
- Xint a,b,c,d,e;
- X{
- X if (Foreground)
- X fprintf (stderr,fs,a,b,c,d,e);
- X fflush (stderr);
- X}
- @//E*O*F sig_set.c//
- if test 4501 -ne "`wc -c <'sig_set.c'`"; then
- echo shar: error transmitting "'sig_set.c'" '(should have been 4501 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'storage.c'" '(1309 characters)'
- if test -f 'storage.c' ; then
- echo shar: will not over-write existing file "'storage.c'"
- else
- sed 's/^X//' >storage.c <<'@//E*O*F storage.c//'
- X/*
- X** vn news reader.
- X**
- X** storage.c - storage allocation routines
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#include <stdio.h>
- X#include "vn.h"
- X
- Xextern char *malloc();
- X
- Xextern int L_allow;
- X
- Xextern PAGE Page;
- X/*
- X Storage allocaters. One more call to malloc in entry_order routine.
- X*/
- X
- Xchar *str_store (s)
- Xchar *s;
- X{
- X static unsigned av_len = 0; /* current storage available */
- X static char *avail;
- X int len;
- X
- X if (s == NULL)
- X s = "";
- X
- X if ((len = strlen(s)+1) > av_len)
- X {
- X if (len > STRBLKSIZE)
- X av_len = len;
- X else
- X av_len = STRBLKSIZE;
- X if ((avail = malloc(av_len)) == NULL)
- X printex ("can't allocate memory for string storage");
- X }
- X strcpy (avail,s);
- X s = avail;
- X avail += len;
- X av_len -= len;
- X return (s);
- X}
- X
- X/*
- X** called after number of terminal lines (L_allow) is known, to set
- X** up storage for Page.
- X*/
- Xpage_alloc ()
- X{
- X char *body;
- X
- X if ((body = malloc(L_allow*sizeof(BODY))) == NULL)
- X printex ("can't allocate memory for display storage");
- X
- X Page.b = (BODY *) body;
- X}
- X
- XNODE
- X*node_store()
- X{
- X static int nd_avail = 0;
- X static NODE *nd;
- X NODE *ret;
- X
- X if (nd_avail <= 0)
- X {
- X if ((nd = (NODE *) malloc(sizeof(NODE)*NDBLKSIZE)) == NULL)
- X printex ("can't allocate memory for newsgroup table");
- X nd_avail = NDBLKSIZE;
- X }
- X --nd_avail;
- X ret = nd;
- X ++nd;
- X return(ret);
- X}
- @//E*O*F storage.c//
- if test 1309 -ne "`wc -c <'storage.c'`"; then
- echo shar: error transmitting "'storage.c'" '(should have been 1309 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'strings.c'" '(720 characters)'
- if test -f 'strings.c' ; then
- echo shar: will not over-write existing file "'strings.c'"
- else
- sed 's/^X//' >strings.c <<'@//E*O*F strings.c//'
- X/*
- X** vn news reader.
- X**
- X** strings.c - character strings
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#include "vn.h"
- X#include "head.h"
- X
- Xchar *Version = "12/86";
- X
- Xchar *No_msg = "No articles";
- Xchar *Hdon_msg = "Headers being printed";
- Xchar *Hdoff_msg = "Headers being suppressed";
- Xchar *Roton_msg = "ROT 13";
- Xchar *Rotoff_msg = "NO ROT";
- X
- Xchar *Aformat = AFORMAT;
- X
- Xchar *Contstr = " ******** any key to continue ********";
- X
- Xchar *R_head = RHEAD;
- Xchar *M_head = MHEAD;
- Xchar *P_head = PHEAD;
- Xchar *D_head = DHEAD;
- Xchar *F_head = FHEAD;
- Xchar *FT_head = FTHEAD;
- Xchar *T_head = THEAD;
- Xchar *L_head = LHEAD;
- Xchar *N_head = NHEAD;
- Xchar *RT_head = RTHEAD;
- Xchar *TO_head = TOHEAD;
- Xchar *DIS_head = DISHEAD;
- @//E*O*F strings.c//
- if test 720 -ne "`wc -c <'strings.c'`"; then
- echo shar: error transmitting "'strings.c'" '(should have been 720 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'tmpnam.c'" '(420 characters)'
- if test -f 'tmpnam.c' ; then
- echo shar: will not over-write existing file "'tmpnam.c'"
- else
- sed 's/^X//' >tmpnam.c <<'@//E*O*F tmpnam.c//'
- X/*
- X** vn news reader.
- X**
- X** tmpnam.c - tmpnam() replacement for UCB, also uses non-generic name.
- X**
- X** see copyright disclaimer / history in vn.c source file
- X*/
- X
- X#include <stdio.h>
- X#include "config.h"
- X
- Xchar *tmpnam (buf)
- Xchar *buf;
- X{
- X static char *ptr = VNTEMPNAME;
- X
- X /* depends on string initialized above */
- X sprintf (ptr+TMP_XOFFSET,"XXXXXX");
- X
- X mktemp (ptr);
- X
- X if (buf != NULL)
- X strcpy (buf,ptr);
- X
- X return (ptr);
- X}
- @//E*O*F tmpnam.c//
- if test 420 -ne "`wc -c <'tmpnam.c'`"; then
- echo shar: error transmitting "'tmpnam.c'" '(should have been 420 characters)'
- fi
- fi # end of overwriting check
- echo shar: "End of archive 1 (of 3)."
- cp /dev/null ark1isdone
- DONE=true
- for I in 1 2 3; do
- if test -! f ark${I}isdone; then
- echo "You still need to run archive ${I}."
- DONE=false
- fi
- done
- case $DONE in
- true)
- echo "You have run all 3 archives."
- echo 'Now read the README'
- ;;
- esac
- ## End of shell archive.
- exit 0
-